/*
 * @Author: mat
 * @Date: 2021-03-29 07:57:37
 * @LastEditTime: 2021-09-15 15:20:39
 * @Description: Cesium 相关公用方法封装
 */

/* global earth addLayer Wind3D Panel */

let infoBoxArray = []; // 信息框元素数组
let infoBoxPreRenderListener = null; // cesium渲染监听
let pointEntities = [];
let modelGraphic = {};

let wind3D = null; // 风场对象
let circleScanArray = []; // 扫描波对象数组
let labelGraphicArray = []; // 文字标数组
let polylineGraphicArray = []; // 线对象数组
let labelEntities = []; // 文字entity对象

let landGeoJsonData = []; // geojson 对象
let arrowLines = []; // 箭头线集合

/**
 * @description: 添加图标
 * @param  {[Array]}  position     [图标位置]
 * @param  {[String]}  img     [图标图片路径]
 * @param  {[Number]}  width     [图片宽度，默认64]
 * @param  {[Number]}  height     [图片高度，默认64]
 * @param  {[String]}  elId     [元素ID, 可不传]
 * @param  {[Function]}  clickFunc     [元素点击回调事件]
 * @param  {[String]}  markerType     [元素类型]
 * @return:
 */
function addIconMarker(position, img, width = 64, height = 64, elId, clickFunc, markerType) {
	let simplePointEntity = viewer.entities.add({
		position: Cesium.Cartesian3.fromDegrees(position[0], position[1]),
		billboard: {
			image: img, // default: undefined
			show: true, // default
			horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // default
			verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // default: CENTER
			// color : Cesium.Color.LIME, // default: WHITE
			width: width,
			height: height,
			// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
			// scaleByDistance: new Cesium.NearFarScalar(30000, 1, 4000000, 0.2),
		},
		elId: elId ? elId : '',
		markerType: markerType ? markerType : '',
		// info: info,
		cursor: true,
	});
	simplePointEntity.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
	if (clickFunc) {
		simplePointEntity['leftClick'] = clickFunc;
	}
	pointEntities.push(simplePointEntity);
}

// 移除所有图标
function removeAllIconMarker() {
	if (pointEntities && pointEntities.length > 0) {
		pointEntities.forEach(item => {
			viewer.entities.remove(item);
		});
		pointEntities = [];
	}
}
// 移除某类型所有图标
function removeMarkerByType(type) {
	for (let i = 0; i < pointEntities.length; i++) {
		if (pointEntities[i].markerType && pointEntities[i].markerType == type) {
			viewer.entities.remove(pointEntities[i]);
			pointEntities.splice(i, 1);
			i--;
		}
	}
}
// 根据elId移除图标
function removeMarkerByElId(elId) {
	for (let i = 0; i < pointEntities.length; i++) {
		if (pointEntities[i].elId && pointEntities[i].elId == elId) {
			viewer.entities.remove(pointEntities[i]);
			pointEntities.splice(i, 1);
			i--;
		}
	}
}

// 添加模型
function addModel(modelUrl, position, name) {
	if (modelGraphic) {
		removeModel();
	}
	modelGraphic = new GV.ModelGraphic({
		name: name ? 'Cam-' + name : '',
		type: 'model',
		visible: true,
		url: modelUrl,
		position: new GV.GeoPoint(position[0], position[1], 30),
		scale: 5,
		color: '',
		heading: 0,
		pitch: 0,
		roll: 0,
		minimumPixelSize: 1.0,
		maximumScale: 10000,
	});
	earth.graphicLayer.add(modelGraphic);
}
// 移除模型
function removeModel() {
	if (modelGraphic) {
		earth.graphicLayer.remove(modelGraphic);
		modelGraphic = null;
	}
}

// 添加扫描波
function radarScan(position, radius = 4000, duration = 900, spreadColor = 'rgba(255,0.0, 0.0,1)') {
	let circleScan = new GV.SpreadGraphic({
		spreadColor: spreadColor,
		position: new GV.GeoPoint(position[0], position[1]),
		radius: radius,
		duration: duration,
	});
	circleScanArray.push(circleScan);
	viewer.graphicLayer.add(circleScan);
}
// 移除扫描波
function removeRadarScan() {
	if (circleScanArray.length > 0) {
		circleScanArray.forEach(item => {
			viewer.graphicLayer.remove(item);
		});
		circleScanArray.length = 0;
	}
}

// 添加文字标
function addLabelGraphic(position, label) {
	let labelGraphic = new GV.LabelGraphic({
		position: new GV.GeoPoint(position[0], position[1], 800),
		text: label,
		font: '25px Helvetica',
		fillColor: '#FF0000',
		heightReference: 'relative_to_ground',
		scaleByDistance: [3000, 1, 4000000, 0.2],
	});
	labelGraphicArray.push(labelGraphic);
	viewer.graphicLayer.add(labelGraphic);
}
// 移除文字标
function removeLabelGraphic() {
	if (labelGraphicArray.length > 0) {
		labelGraphicArray.forEach(item => {
			viewer.graphicLayer.remove(item);
		});
		labelGraphicArray.length = 0;
	}
}

// 添加风场
function init3DWind() {
	const mode = {
		debug: false,
	};

	let panel = new Panel();
	wind3D = new Wind3D(panel, mode, viewer);
	addLayer(g_config.map_service.black_margle_layer1, true);
}
// 移除风场
function remove3DWind() {
	if (wind3D) {
		wind3D.removePrimitives();
		wind3D = null;
	}
}
// 添加线
function addPolylineGraphic(positions, color) {
	let positionList = [];
	positions.forEach(position => {
		let point = new GV.GeoPoint(position[0], position[1]);
		positionList.push(point);
	});
	let polylineGraphic = new GV.PolylineGraphic({
		positions: positions,
		lineStyle: new GV.ColorStyle({
			color: color,
			// icon: GV.DynamicIconEnum.Arrow,
			// duration: 1000,
		}),
		width: 4, // 线宽
		// factor: 15000,
		// step: 50,
	});
	polylineGraphicArray.push(polylineGraphic);
	viewer.graphicLayer.add(polylineGraphic);
}
// 移除线
function removePolylineGraphic() {
	if (polylineGraphicArray.length > 0) {
		polylineGraphicArray.forEach(item => {
			viewer.graphicLayer.remove(item);
		});
		polylineGraphicArray.length = 0;
	}
}
// 添加原生entity
function addLabelEntity(positions, text, currentViewer = viewer) {
	let entity = currentViewer.entities.add({
		name: 'billboard',
		position: Cesium.Cartesian3.fromDegrees(positions[0], positions[1], positions[2] ? positions[2] : 0),
		point: {
			// 点
			pixelSize: 0,
			HeightReference: 1000,
		},
		label: {
			// 文字标签
			text: text,
			font: '500 50px Helvetica', // 15pt monospace
			scale: 0.5,
			style: Cesium.LabelStyle.RED,
			fillColor: Cesium.Color.RED,
			pixelOffset: new Cesium.Cartesian2(0, -30), // 偏移量
			showBackground: true,
			backgroundColor: new Cesium.Color(0, 0, 0, 1),
			scaleByDistance: new Cesium.NearFarScalar(3000, 1, 4000000, 0.2),
		},
		billboard: {},
	});
	labelEntities.push(entity);
}
// 移除原生entity
function removeLabelEntity() {
	if (labelEntities && labelEntities.length > 0) {
		labelEntities.forEach(item => {
			viewer.entities.remove(item);
		});
		labelEntities = [];
	}
}
/**
 * @description: 添加绑定到球上的自定义信息框
 * @param  {[String]}  elId     [元素ID]
 * @param  {[Array]}  positionValue     [坐标值]
 * @param  {[String]}  positionType     [坐标类型, Cartesian3: 笛卡尔空间直角坐标；LonLat 经纬度坐标]
 * @param  {[Boolean]}  removeOld     [是否移除上一个,默认true]
 * @param  {[Number]}  deviateX     [cesium元素与页面左上角x偏移值, 默认为0]
 * @param  {[Number]}  deviateY     [cesium元素与页面左上角y偏移值, 默认为0]
 * @param  {[Number]}  deviateH     [弹出框Y轴额外偏移值（图标高度的一半）]
 * @return:
 */
function addBoundInfoBox(elId, positionValue, positionType, removeOld = true, deviateX = 0, deviateY = 0, deviateH = 0) {
	if (removeOld) {
		removeOldInfoBox();
	}
	const oneDiv = window.document.getElementById(elId);
	if (!oneDiv) {
		return;
	}
	oneDiv.style.display = 'block';
	infoBoxArray.push({
		el: oneDiv,
		positionValue: positionValue,
		positionType: positionType,
	});
	if (infoBoxPreRenderListener) {
		return;
	} else {
		infoBoxPreRenderListener = viewer.scene.preRender.addEventListener(function () {
			infoBoxArray.forEach(item => {
				let elWidth = item.el.offsetWidth;
				let elHeight = item.el.offsetHeight;

				const scratch = new Cesium.Cartesian2(); // cesium二维笛卡尔 笛卡尔二维坐标系就是我们熟知的而二维坐标系；三维也如此
				let position = null;
				if (item.positionType == 'Cartesian3') {
					position = item.positionValue;
				} else if (item.positionType == 'LonLat') {
					position = Cesium.Cartesian3.fromDegrees(item.positionValue[0], item.positionValue[1], 20);
				}
				const canvasPosition = viewer.scene.cartesianToCanvasCoordinates(position, scratch); // cartesianToCanvasCoordinates 笛卡尔坐标（3维度）到画布坐标
				if (Cesium.defined(canvasPosition)) {
					/* 因为cesium 画布位置 和 屏幕位置的偏差，也就是需要减去画布左上角和屏幕左上角的距离 */
					item.el.style.left = canvasPosition.x - elWidth / 2 + deviateX + 'px';
					item.el.style.top = canvasPosition.y - elHeight + deviateY + -deviateH + 'px';
				}
			});
		});
	}
}
// 移除上一个自定义信息框
function removeOldInfoBox() {
	if (infoBoxArray.length && infoBoxArray.length > 0) {
		infoBoxArray[infoBoxArray.length - 1].el.style.display = 'none';
		infoBoxArray.pop();
	} else if (infoBoxPreRenderListener) {
		infoBoxPreRenderListener();
		infoBoxPreRenderListener = null;
	}
}
// 移除所有信息框
function removeAllInfoBox() {
	if (infoBoxArray && infoBoxArray.length && infoBoxArray.length > 0) {
		infoBoxArray.forEach(item => {
			item.el.style.display = 'none';
		});
		infoBoxArray = [];
	}
	if (infoBoxPreRenderListener) {
		infoBoxPreRenderListener();
		infoBoxPreRenderListener = null;
	}
}
// 添加geojson 数据
function addLandGeoJsonData(urlStr, colorStr, callback) {
	let entity = null;
	if (!urlStr) return;

	Cesium.GeoJsonDataSource.load(urlStr).then(dataSource => {
		let color;
		for (let i = 0; i < dataSource.entities.values.length; ++i) {
			entity = dataSource.entities.values[i];
			if (!entity.polygon) continue;
			color = Cesium.Color.fromCssColorString(colorStr).withAlpha(0.1);

			entity.polygon = new Cesium.PolygonGraphics({
				hierarchy: entity.polygon.hierarchy._value,
				outline: false,
				material: color,
				classificationType: Cesium.ClassificationType.TERRAIN,
				zIndex: 10,
			});

			entity.polyline = new Cesium.PolylineGraphics({
				positions: [...entity.polygon.hierarchy._value.positions, entity.polygon.hierarchy._value.positions[0]],
				width: 1,
				material: Cesium.Color.fromCssColorString(colorStr),
				clampToGround: true,
				classificationType: Cesium.ClassificationType.TERRAIN,
				// zIndex:1
			});

			entity.cursor = true;
			// let holes = entity.polygon.hierarchy._value.holes
			// for (let j = 0; j < holes.length; ++j) {
			// 	dataSource.entities.add({
			// 		polyline: {
			// 			positions: [...holes[j].positions, holes[j].positions[0]],
			// 			width: 3,
			// 			clampToGround: true,
			// 			material: color,
			// 			classificationType: Cesium.ClassificationType.TERRAIN,
			// 			zIndex: 1,
			// 		},
			// 	})
			// }
		}

		landGeoJsonData.push(dataSource);
		viewer.dataSources.add(dataSource);
		callback(dataSource.entities.values);
	});
}

// 移除geojson 数据
function removeLandGeoJsonData() {
	for (let i = 0; i < landGeoJsonData.length; ++i) {
		viewer.dataSources.remove(landGeoJsonData[i]);
	}
	landGeoJsonData.length = 0;
	landGeoJsonData = [];
}
// 添加两点间的箭头线
function addArrowLine(points) {
	let point1 = new GV.GeoPoint(points[0][0], points[0][1]);
	let point2 = new GV.GeoPoint(points[1][0], points[1][1]);
	let positions = [point1, point2];
	let arrowLine = new GV.ParabolaLineGraphic({
		positions: positions,
		lineStyle: new GV.DynamicStyle({
			color: '#00FF99',
			icon: GV.DynamicIconEnum.Arrow,
			duration: 1000,
		}),
		width: 5, // 线宽
		factor: 15000,
		step: 50,
	});
	viewer.graphicLayer.add(arrowLine);
	arrowLines.push(arrowLine);
}

// 移除全部箭头线
function removeArrowLine() {
	if (arrowLines && arrowLines.length > 0) {
		arrowLines.forEach(item => {
			viewer.graphicLayer.remove(item);
		});
		arrowLines = [];
	}
}

export {
	addIconMarker,
	removeAllIconMarker,
	removeMarkerByType,
	removeMarkerByElId,
	addModel,
	removeModel,
	radarScan,
	removeRadarScan,
	addLabelGraphic,
	removeLabelGraphic,
	init3DWind,
	remove3DWind,
	addPolylineGraphic,
	removePolylineGraphic,
	addLabelEntity,
	removeLabelEntity,
	addBoundInfoBox,
	removeAllInfoBox,
	addLandGeoJsonData,
	removeLandGeoJsonData,
	addArrowLine,
	removeArrowLine,
};
